﻿using System;
using System.Data;
using System.Globalization;
using ContractManagementSystem.Common;
using ContractManagementSystem.DataAccess;
using ContractManagementSystem.Entity;

namespace ContractManagementSystem.BusinessLogic
{
    public static class TimesheetBusiness
    {
        public static string ErrorMessage { get; set; }

        private static TimesheetDataAccess _timesheet;
        private static ContractDataAccess _contract;
        private static LogDataAccess _logDataAccess;

        /// <summary>
        /// Function create new timesheet
        /// </summary>
        /// <param name="contractId"></param>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DataTable CreateNew(Guid contractId, DateTime dateTime)
        {
            _contract = new ContractDataAccess();
            var result = new DataTable { Locale = CultureInfo.CurrentCulture };
            result.Columns.Add("WorkDate", typeof(DateTime));
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return result;
            }

            DataTable sourceDate = _contract.FetchContractDateById(contractId);
            DateTime startDate = Convert.ToDateTime(sourceDate.Rows[0]["StartDate"], CultureInfo.CurrentCulture);
            DateTime endDate = Convert.ToDateTime(sourceDate.Rows[0]["EndDate"], CultureInfo.CurrentCulture);

            DateTime modifiedDate = (dateTime > endDate || dateTime < startDate) ? endDate : dateTime;

            for (int i = 1; i <= 7; i++)
            {
                if (modifiedDate < startDate) break;
                result.Rows.Add(modifiedDate);
                result.Rows.Add(modifiedDate);
                modifiedDate = modifiedDate.AddDays(-1);
            }

            return result;
        }

        /// <summary>
        /// Function Update Timesheet.
        /// Author: Group2.TuanCH - 10:59AM 07/05/2012
        /// </summary>
        /// <param name="timesheetEntity">ContractManagementSystem.Entity.TimesheetEntity</param>
        /// <returns> 1 if update succeed; otherwise 0 </returns>
        public static int Update(TimesheetEntity timesheetEntity)
        {
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return 0;
            }
            int result = _timesheet.Update(timesheetEntity);

            return result;
        }

        /// <summary>
        /// Function BatchUpdate 
        /// Author: Group2.TuanCH - 2:05PM 07/18/2012
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int BatchUpdate(DataTable source)
        {
            _logDataAccess = new LogDataAccess();
            string errorMessageLog = "Update Timesheet is fail. ERROR: ";
            string evenMessageLog = "Update Timesheet success. Updated ";
            int result = 0;
            ValidateHelper.RemoveRowsNull(source);
            _contract = new ContractDataAccess();
            var contractId = new Guid(source.Rows[0]["ContractId"].ToString());
            DataTable sourceDate = _contract.FetchContractDateById(contractId);

            if (ValidateHelper.IsValidDataTableNotNull(sourceDate))
            {
                DateTime startDate = Convert.ToDateTime(sourceDate.Rows[0]["StartDate"], CultureInfo.CurrentCulture);
                DateTime endDate = Convert.ToDateTime(sourceDate.Rows[0]["EndDate"], CultureInfo.CurrentCulture);

                for (int i = 0; i < source.Rows.Count; i++)
                {
                    var descriptionInRow = source.Rows[i]["Description"].ToString();
                    var workingTimeInRow = float.Parse(source.Rows[i]["WorkingTime"].ToString(), CultureInfo.CurrentCulture);
                    var workDateInRow = Convert.ToDateTime(source.Rows[i]["WorkDate"].ToString(), CultureInfo.CurrentCulture);

                    if (string.IsNullOrEmpty(descriptionInRow.Trim()) || workDateInRow > endDate ||
                        workDateInRow < startDate || !ValidateHelper.IsValidFloat(workingTimeInRow.ToString(CultureInfo.CurrentCulture)) ||
                        workingTimeInRow < 0 || workingTimeInRow > 24)
                    {
                        source.Rows.RemoveAt(i);
                    }
                }
                _timesheet = new TimesheetDataAccess();
                if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
                {
                    ErrorMessage = _timesheet.ErrorMessage;
                    return 0;
                }
                if (source.Rows.Count > 0)
                {
                    result = _timesheet.BatchUpdate(source, BatchType.Update);
                    if (result <= 0)
                    {
                        ErrorMessage = _timesheet.ErrorMessage;
                        errorMessageLog += ErrorMessage;
                        _logDataAccess.WriteError(errorMessageLog, "");
                    }
                    else
                    {
                        evenMessageLog += result + " row(s).";
                        _logDataAccess.WriteEvent(evenMessageLog,"");
                    }
                }
            }
            else
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage + " System do not get start date and end date of this contract: " + contractId + ".";
                _logDataAccess.WriteError(errorMessageLog, "");

                return 0;
            }

            return result;
        }

        /// <summary>
        /// Function Insert Timesheet.
        /// Author: Group2.TuanCH - 11:10AM 07/05/2012
        /// </summary>
        /// <param name="timesheetEntity">ContractManagementSystem.Entity.TimesheetEntity</param>
        /// <returns> 1 if insert succeed; otherwise 0 </returns>
        public static int Insert(TimesheetEntity timesheetEntity)
        {
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return 0;
            }
            int result = _timesheet.Insert(timesheetEntity);

            return result;
        }

        /// <summary>
        /// Function BatchInsert
        /// Author: Groupp2.TuanCH - 2:10PM 07/18/2012
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int BatchInsert(DataTable source)
        {
            _logDataAccess = new LogDataAccess();
            string errorMessageLog = "Insert Timesheet is fail. ERROR: ";
            string evenMessageLog = "Insert Timesheet success. Inserted ";
            int result = 0;
            ValidateHelper.RemoveRowsNull(source);
            _contract = new ContractDataAccess();
            var contractId = new Guid(source.Rows[0]["ContractId"].ToString());
            DataTable sourceDate = _contract.FetchContractDateById(contractId);

            if (ValidateHelper.IsValidDataTableNotNull(sourceDate))
            {
                DateTime startDate = Convert.ToDateTime(sourceDate.Rows[0]["StartDate"], CultureInfo.CurrentCulture);
                DateTime endDate = Convert.ToDateTime(sourceDate.Rows[0]["EndDate"], CultureInfo.CurrentCulture);

                for (int i = 0; i < source.Rows.Count; i++)
                {
                    var descriptionInRow = source.Rows[i]["Description"].ToString();
                    var workingTimeInRow = float.Parse(source.Rows[i]["WorkingTime"].ToString(), CultureInfo.CurrentCulture);
                    var workDateInRow = Convert.ToDateTime(source.Rows[i]["WorkDate"].ToString(), CultureInfo.CurrentCulture);

                    if(string.IsNullOrEmpty(descriptionInRow.Trim()) || workDateInRow > endDate ||
                        workDateInRow < startDate || !ValidateHelper.IsValidFloat(workingTimeInRow.ToString(CultureInfo.CurrentCulture)) ||
                        workingTimeInRow < 0 || workingTimeInRow > 24)
                    {
                        source.Rows.RemoveAt(i);
                    }
                }
                _timesheet = new TimesheetDataAccess();
                if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
                {
                    ErrorMessage = _timesheet.ErrorMessage;
                    return 0;
                }
                if (source.Rows.Count > 0)
                {
                    result = _timesheet.BatchUpdate(source, BatchType.Insert);
                    if (result <= 0)
                    {
                        ErrorMessage = _timesheet.ErrorMessage;
                        errorMessageLog += ErrorMessage;
                        _logDataAccess.WriteError(errorMessageLog, "");
                    }
                    else
                    {
                        evenMessageLog += result + " row(s).";
                        _logDataAccess.WriteEvent(evenMessageLog, "");
                    }
                }
            }
            else
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage + " System do not get start date and end date of this contract: " + contractId + ".";
                _logDataAccess.WriteError(errorMessageLog, "");

                return 0;
            }

            return result;
        }

        /// <summary>
        /// Function Delete Timesheet.
        /// Author: Group2.TuanCH - 11:14AM 07/05/2012
        /// </summary>
        /// <param name="id">ContractManagementSystem.Entity.TimesheetEntity.Id</param>
        /// <returns> 1 if deletes succeed; otherwise 0 </returns>
        public static int Delete(Guid id)
        {
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return 0;
            }
            int result = _timesheet.Delete(id);

            return result;
        }

        /// <summary>
        /// Function BatchDelete
        /// Author: Group2.TuanCH - 2:14PM 07/18/2012
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int BatchDelete(DataTable source)
        {
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return 0;
            }
            int result = _timesheet.BatchUpdate(source, BatchType.Delete);

            return result;
        }

        /// <summary>
        /// Function Reject Timesheet.
        /// Author: Group2.TuanCH - 1:41PM 07/05/2012
        /// </summary>
        /// <param name="id">Guid: ContractManagementSystem.Entity.TimesheetEntity.Id</param>
        /// <param name="content">string: ContractManagementSystem.Entity.ReasonEntity.Content</param>
        /// <returns> 1 if reject succeed; otherwise 0 </returns>
        public static int RejectTimesheet(Guid id, string content)
        {
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return 0;
            }
            int result = _timesheet.RejectTimesheet(id, content);

            return result;
        }

        /// <summary>
        /// Function BatchReject
        /// Author: Group2.TuanCH - 2:14PM 07/18/2012
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int BatchReject(DataTable source)
        {
            _logDataAccess = new LogDataAccess();
            string errorMessageLog = "Reject Timesheet is fail. ERROR: ";
            string evenMessageLog = "Reject Timesheet success. Rejected ";
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog,"");
                return 0;
            }
            int result = _timesheet.BatchUpdate(source, BatchType.Reject);

            if(result <= 0)
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
            }
            else
            {
                evenMessageLog += result + " row(s).";
                _logDataAccess.WriteEvent(evenMessageLog,"");
            }

            return result;
        }

        /// <summary>
        /// Function Approved Timesheet.
        /// Author: Group2.TuanCH - 4:53PM 07/10/2012
        /// </summary>
        /// <param name="id">Guid: ContractManagementSystem.Entity.TimesheetEntity.Id</param>
        /// <returns> 1 if reject succeed; otherwise 0 </returns>
        public static int ApprovedTimesheet(Guid id)
        {
            _logDataAccess = new LogDataAccess();
            string errorMessageLog = "Approve Timesheet is fail. ERROR: ";
            string evenMessageLog = "Approve Timesheet success. Approved ";
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
                return 0;
            }
            int result = _timesheet.ApprovedTimesheet(id);

            if (result <= 0)
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
            }
            else
            {
                evenMessageLog += result + " row(s).";
                _logDataAccess.WriteEvent(evenMessageLog, "");
            }

            return result;
        }

        /// <summary>
        /// Function BatchApproved
        /// Author: Group2.TuanCH - 2:14PM 07/18/2012
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int BatchApproved(DataTable source)
        {
            _logDataAccess = new LogDataAccess();
            string errorMessageLog = "Approve Timesheet is fail. ERROR: ";
            string evenMessageLog = "Approve Timesheet success. Approved ";
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
                return 0;
            }
            int result = _timesheet.BatchUpdate(source, BatchType.Approved);

            if (result <= 0)
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
            }
            else
            {
                evenMessageLog += result + " row(s).";
                _logDataAccess.WriteEvent(evenMessageLog, "");
            }

            return result;
        }

        /// <summary>
        /// Function Inactive Timesheet.
        /// Author: Group2.TuanCH - 4:55PM 07/10/2012
        /// </summary>
        /// <param name="id">Guid: ContractManagementSystem.Entity.TimesheetEntity.Id</param>
        /// <returns> 1 if reject succeed; otherwise 0 </returns>
        public static int Inactive(Guid id)
        {
            _logDataAccess = new LogDataAccess();
            string errorMessageLog = "Inactive Timesheet is fail. ERROR: ";
            string evenMessageLog = "Inactive Timesheet success. Inactived ";
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
                return 0;
            }
            int result = _timesheet.Inactive(id);

            if (result <= 0)
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
            }
            else
            {
                evenMessageLog += result + " row(s).";
                _logDataAccess.WriteEvent(evenMessageLog, "");
            }

            return result;
        }

        /// <summary>
        /// Function BatchInactive
        /// Author: Group2.TuanCH - 2:14PM 07/18/2012
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int BatchInactive(DataTable source)
        {
            _logDataAccess = new LogDataAccess();
            string errorMessageLog = "Inactive Timesheet is fail. ERROR: ";
            string evenMessageLog = "Inactive Timesheet success. Inactived ";
            _timesheet = new TimesheetDataAccess();
            if (!string.IsNullOrEmpty(_timesheet.ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
                return 0;
            }
            int result = _timesheet.BatchUpdate(source, BatchType.Inactive);

            if (result <= 0)
            {
                ErrorMessage = _timesheet.ErrorMessage;
                errorMessageLog += ErrorMessage;
                _logDataAccess.WriteError(errorMessageLog, "");
            }
            else
            {
                evenMessageLog += result + " row(s).";
                _logDataAccess.WriteEvent(evenMessageLog, "");
            }

            return result;
        }

        /// <summary>
        /// Function Get all data of Timesheet.
        /// Author: Group2.TuanCH - 4:59PM 07/10/2012
        /// </summary>
        /// <returns> DataTable of Timesheet </returns>
        public static DataTable FetchAll()
        {
            _timesheet = new TimesheetDataAccess();
            var result = new DataTable { Locale = CultureInfo.CurrentCulture };
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return result;
            }
            result = _timesheet.FetchAll();

            return result;
        }

        /// <summary>
        /// Function Get data of Timesheet by ContracId.
        /// Author: Group2.TuanCH - 5:03PM 07/10/2012
        /// </summary>
        /// <param name="contractId">Guid: ContractManagementSystem.Entity.ContractEntity.ContractId</param>
        /// <returns> DataTable of timesheet </returns>
        public static DataTable FetchByContractId(Guid contractId)
        {
            _timesheet = new TimesheetDataAccess();
            var result = new DataTable { Locale = CultureInfo.CurrentCulture };
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return result;
            }
            result = _timesheet.FetchByContractId(contractId);

            return result;
        }

        /// <summary>
        /// Function Get data of Timesheet by TimesheetId.
        /// Author: Group2.TuanCH - 08:58PM 07/15/2012
        /// </summary>
        /// <param name="timesheetId">Guid: ContractManagementSystem.Entity.ContractEntity.TimesheetId</param>
        /// <returns> DataTable of timesheet </returns>
        public static DataTable FetchByTimesheetId(Guid timesheetId)
        {
            _timesheet = new TimesheetDataAccess();
            var result = new DataTable { Locale = CultureInfo.CurrentCulture };
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return result;
            }
            result = _timesheet.FetchByTimesheetId(timesheetId);

            return result;
        }

        /// <summary>
        /// Function Get data from datatable by Id
        /// Author: Group2.TuanCh - 03:58PM 07/16/2012
        /// </summary>
        /// <param name="id"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        public static DataTable FetchById(int[] id, DataTable source)
        {
            var dataTable = new DataTable { Locale = CultureInfo.CurrentCulture };
            dataTable.Columns.Add("TimesheetId", typeof(string));
            dataTable.Columns.Add("WorkDate", typeof(DateTime));
            dataTable.Columns.Add("WorkingTime", typeof(float));
            dataTable.Columns.Add("Description", typeof(string));
            dataTable.Columns.Add("Status", typeof(string));
            dataTable.Columns.Add("Id", typeof(int));

            int resultId = 0;
            foreach (int value in id)
            {
                string timesheetId = source.Rows[value]["TimesheetId"].ToString();
                DateTime createDate = Convert.ToDateTime(source.Rows[value]["WorkDate"], CultureInfo.CurrentCulture);
                float workingTime = float.Parse(source.Rows[value]["WorkingTime"].ToString(), CultureInfo.CurrentCulture);
                string description = source.Rows[value]["Description"].ToString();
                string status = source.Rows[value]["Status"].ToString();

                dataTable.Rows.Add(timesheetId, createDate, workingTime, description, status, resultId);
                resultId++;
            }

            return dataTable;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static DataTable FetchByUserId(Guid userId)
        {
            _timesheet = new TimesheetDataAccess();
            var result = new DataTable { Locale = CultureInfo.CurrentCulture };
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return result;
            }
            result = _timesheet.FetchByUserId(userId);

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fromDate"></param>
        /// <param name="toDate"></param>
        /// <param name="contractId"></param>
        /// <param name="contractorId"></param>
        /// <param name="statusParameter"></param>
        /// <returns></returns>
        public static DataTable TimesheetSearch(DateTime fromDate, DateTime toDate, Guid contractId, Guid contractorId, string statusParameter)
        {
            _timesheet = new TimesheetDataAccess();
            var result = new DataTable { Locale = CultureInfo.CurrentCulture };
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return result;
            }
            result = _timesheet.TimesheetSearch(fromDate, toDate, contractId, contractorId, statusParameter);

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="timesheetId"></param>
        /// <returns></returns>
        public static DataTable FetchReasonByTimesheetId(Guid timesheetId)
        {
            _timesheet = new TimesheetDataAccess();
            var result = new DataTable { Locale = CultureInfo.CurrentCulture };
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ErrorMessage = _timesheet.ErrorMessage;
                return result;
            }
            result = _timesheet.FetchReasonByTimesheetId(timesheetId);

            return result;
        }
    }
}
